package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.system.domain.ProTask;
import com.ruoyi.system.domain.bo.ProTaskBo;
import com.ruoyi.system.domain.bo.ProTaskTempBo;
import com.ruoyi.system.domain.vo.ProSubjectTempVo;
import com.ruoyi.system.domain.vo.ProTaskTempVo;
import com.ruoyi.system.domain.vo.ProTaskVo;
import com.ruoyi.system.mapper.ProTaskMapper;
import com.ruoyi.system.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.bo.ProSubjectBo;
import com.ruoyi.system.domain.vo.ProSubjectVo;
import com.ruoyi.system.domain.ProSubject;
import com.ruoyi.system.mapper.ProSubjectMapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 项目管理Service业务层处理
 *
 * @author ruoyi
 * @date 2023-05-07
 */
@RequiredArgsConstructor
@Service
public class ProSubjectServiceImpl implements IProSubjectService {

    private final ProSubjectMapper baseMapper;

    private final ISysUserService sysUserService;


    private final IWxService wxService;


    private final IProSubjectTempService proSubjectTempService;


    private final IProTaskTempService proTaskTempService;

    private final ProTaskMapper proTaskMapper;

    /**
     * 查询项目管理
     */
    @Override
    public ProSubjectVo queryById(Long subjectId){
        ProSubjectVo proSubjectVo = baseMapper.selectVoById(subjectId);
        proSubjectVo.setHeadUsers(this.parseUsersBynames(proSubjectVo.getHeadUser()));
        proSubjectVo.setCopyUsers(this.parseUsersBynames(proSubjectVo.getCopyUser()));
        return proSubjectVo;
    }

    /**
     * 查询项目管理列表
     */
    @Override
    public TableDataInfo<ProSubjectVo> queryPageList(ProSubjectBo bo, PageQuery pageQuery) {
        QueryWrapper<ProSubject> lqw = buildQuery(bo);
//        String username = LoginHelper.getUsername();
//        if(!"admin".equals(username)){
//            lqw.and(lq->{
//                lq.eq(ProSubject::getCreateBy, username)
//                    .or()
//                    .like(ProSubject::getHeadUser, username+",")
//                    .or()
//                    .like(ProSubject::getCopyUser, username+",");
//            });
//        }
        Page<ProSubjectVo> result = baseMapper.selectPageList(pageQuery.build(), lqw);
        result.getRecords().forEach(item->{
            item.setHeadUsers(this.parseUsersBynames(item.getHeadUser()));
            item.setCopyUsers(this.parseUsersBynames(item.getCopyUser()));
            List<ProTaskVo> proTaskVos = proTaskMapper.selectVoList(new LambdaQueryWrapper<ProTask>().eq(ProTask::getSubjectId, item.getSubjectId()));
            item.setTaskList(proTaskVos);
        });
        return TableDataInfo.build(result);
    }


    private ArrayList<SysUser> parseUsersBynames(String headUser){
        ArrayList<SysUser> headUsers = new ArrayList<>();
        if(StringUtils.isNotBlank(headUser)){
            String[] split = headUser.split(",");
            for (String username : split) {
                SysUser sysUser = sysUserService.selectUserByUserName(username);
                if(ObjectUtils.isNotNull(sysUser)){
                    headUsers.add(sysUser);
                }
            }
        }
        return headUsers;
    }
    /**
     * 查询项目管理列表
     */
    @Override
    public List<ProSubjectVo> queryList(ProSubjectBo bo) {
        QueryWrapper<ProSubject> lqw = buildQuery(bo);
        return baseMapper.selectVoList(lqw);
    }
    private QueryWrapper<ProSubject> buildQuery(ProSubjectBo bo) {
        String username = LoginHelper.getUsername();
        Map<String, Object> params = bo.getParams();
        QueryWrapper<ProSubject> queryWrapper = new QueryWrapper<>();
        if(!"admin".equals(username)) {
            queryWrapper.and(lqw -> {
                lqw.eq("pt.create_by", username).or();
                lqw.like("pt.head_user", username + ",").or();
                lqw.like("pt.copy_user", username + ",").or();
                lqw.eq("ps.create_by", username).or();
                lqw.like("ps.head_user", username + ",").or();
                lqw.like("ps.copy_user", username + ",");
            });
        }
        queryWrapper.like(StringUtils.isNotBlank(bo.getSubjectName()), "ps.subject_name", bo.getSubjectName());
        queryWrapper.eq(StringUtils.isNotBlank(bo.getStatus()), "ps.status", bo.getStatus());
        queryWrapper.eq(StringUtils.isNotBlank(bo.getCategory()), "ps.category", bo.getCategory());
        queryWrapper.orderBy(true,false,"ps.create_time");
        return queryWrapper;
    }
    private LambdaQueryWrapper<ProSubject> buildQueryWrapper(ProSubjectBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ProSubject> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getSubjectNo()), ProSubject::getSubjectNo, bo.getSubjectNo());
        lqw.eq(bo.getDdate() != null, ProSubject::getDdate, bo.getDdate());
        lqw.like(StringUtils.isNotBlank(bo.getSubjectName()), ProSubject::getSubjectName, bo.getSubjectName());
        lqw.eq(StringUtils.isNotBlank(bo.getDesp()), ProSubject::getDesp, bo.getDesp());
        lqw.eq(bo.getFireDate() != null, ProSubject::getFireDate, bo.getFireDate());
        lqw.eq(bo.getDemandDate() != null, ProSubject::getDemandDate, bo.getDemandDate());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ProSubject::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增项目管理
     */
    @Override
    public Boolean insertByBo(ProSubjectBo bo) {
        ProSubject add = BeanUtil.toBean(bo, ProSubject.class);
        add.setStatus(ProSubject.STATUS_NEW);
        add.setSubjectNo(new Date().getTime()+"");
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
//        if(StringUtils.isNotEmpty(bo.getHeadUser())||StringUtils.isNotEmpty(bo.getCopyUser())){
//            String msg = generateMsgByProSubject(bo);
//            wxService.sendMessageByText2Copy(
//                bo.getCopyUser().replace(",","|")
//                    +bo.getHeadUser().replace(",","|"),
//                this.generateUrl("http://emswx.kennede.com:49865/prod-api/unauth/toList?id="+add.getSubjectId()),
//                bo.getSubjectName(),
//                msg);
//
//            wxService.sendMessage2Copy(
//                bo.getCopyUser().replace(",","|")
//                    +bo.getHeadUser().replace(",","|"),
//                this.generateUrl("http://emswx.kennede.com:49865/prod-api/unauth/toDetail?id="+add.getTaskId()),
//                msg);
//        }
        if (flag) {
            bo.setSubjectId(add.getSubjectId());
        }
        return flag;
    }

    /**
     * 修改项目管理
     */
    @Override
    public Boolean updateByBo(ProSubjectBo bo) {
        ProSubject update = BeanUtil.toBean(bo, ProSubject.class);
        if(!canEdit(bo)){
            throw new ServiceException("你没有编辑权限");
        }
        validEntityBeforeSave(update);
        if(StringUtils.isNotEmpty(bo.getHeadUser())||StringUtils.isNotEmpty(bo.getCopyUser())){
            String msg = generateMsgByProSubject(bo);
            wxService.sendMessageByText2Copy(
                this.parseUserBySubject(bo),
                this.generateUrl("http://emswx.kennede.com:49865/prod-api/unauth/toList?id="+bo.getSubjectId()),
                bo.getSubjectName(),
                msg);
        }
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ProSubject entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除项目管理
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean generateByTemplate(Long tempId) {
        ProSubjectTempVo proSubjectTempVo = proSubjectTempService.queryById(tempId);
        ProTaskTempBo proTaskTempBo = new ProTaskTempBo();
        proTaskTempBo.setSubjectId(tempId);
        List<ProTaskTempVo> proTaskTempVos = proTaskTempService.queryList(proTaskTempBo);
        ProSubjectBo proSubjectBo = BeanUtil.toBean(proSubjectTempVo, ProSubjectBo.class);
        proSubjectBo.setSubjectId(null);
        proSubjectBo.setSubjectNo(new Date().getTime()+"");
        proSubjectBo.setStatus(ProSubject.STATUS_NEW);
        proSubjectBo.setCreateBy(null);
        proSubjectBo.setUpdateBy(null);
        proSubjectBo.setCreateTime(null);
        proSubjectBo.setUpdateTime(null);
        insertByBo(proSubjectBo);
        for (ProTaskTempVo proTaskTempVo : proTaskTempVos) {
            ProTask proTaskBo = BeanUtil.toBean(proTaskTempVo, ProTask.class);
            proTaskBo.setSubjectId(proSubjectBo.getSubjectId());
            proTaskBo.setSubjectNo(proSubjectBo.getSubjectNo());
            proTaskBo.setSubjectName(proSubjectBo.getSubjectName());
            proTaskBo.setTaskId(null);
            proTaskBo.setCreateBy(null);
            proTaskBo.setUpdateBy(null);
            proTaskBo.setCreateTime(null);
            proTaskBo.setUpdateTime(null);
            proTaskMapper.insert(proTaskBo);
        }


        return true;
    }

    private boolean canEdit(ProSubjectBo bo){
        String username = LoginHelper.getLoginUser().getUsername();
        if("admin".equals(username)){
            return true;
        }
        ProSubject proSubject = baseMapper.selectById(bo.getSubjectId());
        return proSubject.getCreateBy().equals(username)||
            proSubject.getHeadUser().contains(username);
    }
    private String generateUrl(String uri){
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"+
            "appid=wwe7858c0d51254286"+
            "&redirect_uri="+uri+
            "&response_type=code&scope=snsapi_userinfo&state=STATE"+
            "&agentid=1000013#wechat_redirect";
        return url;
    }
    private String parseUserBySubject(ProSubjectBo bo){
        String users = "";
        Set<String> userSet = new HashSet<>();
        userSet.addAll(this.parseUser2Set(bo.getHeadUser()));
        userSet.addAll(this.parseUser2Set(bo.getCopyUser()));
        List<ProTaskVo> proTaskVos = proTaskMapper.selectVoList
            (new LambdaQueryWrapper<ProTask>().eq(ProTask::getSubjectId,
                bo.getSubjectId()));
        for (ProTaskVo proTaskVo : proTaskVos) {
            userSet.addAll(this.parseUser2Set(proTaskVo.getHeadUser()));
            userSet.addAll(this.parseUser2Set(proTaskVo.getCopyUser()));
        }
        Iterator<String> iterator = userSet.iterator();
        while (iterator.hasNext()){
            String next = iterator.next();
            if(StringUtils.isNotBlank(next)){
                users +=  next + "|";
            }
        }
        return users;
    }
    private Set<String> parseUser2Set(String users){
        Set<String> userSet = new HashSet<>();
        if(StringUtils.isNotBlank(users)){
            String[] split = users.split(",");
            for (String s : split) {
                userSet.add(s);
            }
        }
        return userSet;
    }
    private String generateMsgByProSubject(ProSubjectBo bo){
        String msg = "项目："+bo.getSubjectName();
        msg += ",描述： "+bo.getDesp();
        return msg;
    }
}
